package cn.lg.soar.cloud.common.config;

import cn.lg.soar.common.constant.MDCKey;
import cn.lg.soar.common.util.IpUtil;
import cn.lg.soar.common.util.current.ICurrentUser;
import cn.lg.soar.common.util.data.SecureRandomUtil;
import cn.lg.soar.core.util.FeignSecretUtils;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.slf4j.MDC;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.crypto.spec.SecretKeySpec;

/**
 * feign调用前设置客户端地址和当前用户
 * @author luguoxiang
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class FeignSecretRequestInterceptor implements RequestInterceptor {


    private final SecretKeySpec keySpec;

    public FeignSecretRequestInterceptor(CloudProperties properties) {
        keySpec = FeignSecretUtils.getKeySpec(properties.getSecret());
    }

    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        String random;
        String expire;
        String sign;
        if (attributes != null) {
            // 准备数据
            jakarta.servlet.http.HttpServletRequest request = attributes.getRequest();
            String userInfo = request.getHeader(ICurrentUser.USER_KEY);
            sign = request.getHeader(FeignSecretUtils.SIGN_KEY);
            if (sign == null) {
                random = SecureRandomUtil.getString(32);
                expire = String.valueOf(System.currentTimeMillis() + FeignSecretUtils.EXPIRE);
                sign = FeignSecretUtils.sign(keySpec, userInfo, random, expire);
            } else {
                random = request.getHeader(FeignSecretUtils.RANDOM_KEY);
                expire = request.getHeader(FeignSecretUtils.EXPIRE_KEY);
            }
            // 设置请求头
            requestTemplate.header("User-Agent", request.getHeader("User-Agent"));
            requestTemplate.header(ICurrentUser.USER_KEY, userInfo);
            requestTemplate.header(IpUtil.CLIENT_IP, IpUtil.getRemoteIp(request));
        } else {
            // 设置请求头
            random = SecureRandomUtil.getString(32);
            expire = String.valueOf(System.currentTimeMillis() + FeignSecretUtils.EXPIRE);
            sign = FeignSecretUtils.sign(keySpec, null, random, expire);
        }
        requestTemplate.header(MDCKey.TRACE_ID, MDC.get(MDCKey.TRACE_ID));
        // 安全验证请求头
        requestTemplate.header(FeignSecretUtils.RANDOM_KEY, random);
        requestTemplate.header(FeignSecretUtils.EXPIRE_KEY, expire);
        requestTemplate.header(FeignSecretUtils.SIGN_KEY, sign);
    }
}
